package com.haier.npt;

import java.math.BigInteger;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.support.RequestContextUtils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.haier.npt.user.UserHandlerMethodArgumentResolver;

@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter{

	@Value("${sso.userinfo.enable:true}")
	private boolean userEnable;
	
	public HandlerMethodArgumentResolver userArgumentResolver(){
		return new UserHandlerMethodArgumentResolver();
	}
	
	@Override
	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers){
		if(userEnable){
			argumentResolvers.add(userArgumentResolver());
		}
		super.addArgumentResolvers(argumentResolvers);
	}
	
	@Override
	public void addInterceptors(InterceptorRegistry registry){
		super.addInterceptors(registry);
		registry.addInterceptor(new LocaleChangeInterceptor());
	}
	
	@Bean
	public ReloadableResourceBundleMessageSource messageSource(){
		ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
		messageSource.setBasenames("classpath:i18n/message","classpath:i18n/i18n");
		messageSource.setDefaultEncoding("UTF-8");
		//如果抛出异常，则使用messageKey作为异常信息，默认是false
		messageSource.setUseCodeAsDefaultMessage(true);
		return messageSource;
	}
	
	/**
	 * @Description: 重写JSR303消息资源文件，动态加载国际化资源文件
	 * @param: @return      
	 * @return: LocalValidatorFactoryBean      
	 * @throws   
	 */
	@Bean
	public LocalValidatorFactoryBean validator(){
		LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
		validator.setValidationMessageSource(messageSource());
		return validator;
	}
	
	@Bean
	public LocaleResolver localeResolver(){
		AcceptHeaderLocaleResolver localeResolver = new MyAcceptHeaderLocaleResolver();
		return localeResolver;
	}
	
	/**
	 * @Description:设置locale和时区 
	 * @author: lixu
	 * @date:   2018年7月16日 上午10:21:36   
	 */
	public static class MyAcceptHeaderLocaleResolver extends AcceptHeaderLocaleResolver{
		@Override
		public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale){
			//从请求中获取TimeZone，如果没有返回null
			TimeZone tz = RequestContextUtils.getTimeZone(request);
			if(tz == null){
				String timeZoneValue = request.getParameter("timeZone");
				if(timeZoneValue != null){
					tz = TimeZone.getTimeZone(timeZoneValue);
				}
				if(tz == null){
					tz = TimeZone.getDefault();
				}
			}
			//设置local
			LocaleContextHolder.setLocale(locale,true);
			//利用LocaleContextHolder来设置或者读取TimeZone
			LocaleContextHolder.setTimeZone(tz,true);
		}
	}
	
	/**
	 * @Description: 配置使用FastJson替代jackJson的spring mvc 配置
	 * @param: @return      
	 * @return: void      
	 * @throws   
	 */
	@Override
	public void configureMessageConverters(List<HttpMessageConverter<?>> converters){
		super.configureMessageConverters(converters);
		MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
		ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();
		SimpleModule simpleModule = new SimpleModule();
		objectMapper.setSerializerFactory(objectMapper.getSerializerFactory().withSerializerModifier(new CustomBeanSerializerModifier()));
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        jackson2HttpMessageConverter.setObjectMapper(objectMapper);
        //放到第一个
        converters.add(0, jackson2HttpMessageConverter);
	}
}
